<template>
	<view>
		<view class="input-box" v-if="input.type == 'input-text'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<input class="input" :placeholder="input.desc.length ? input.desc : '请填写' + input.name" v-model="result"
					placeholder-style="color:#909090;font-size:14px" :disabled="input.show" />
			</view>
		</view>

		<view class="input-box" v-else-if="input.type == 'input-textarea'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background: #f9f9f9;border-radius: 10px">
				<textarea class="input" style="height: 80px;width: 100%;padding: 0;" v-model="result"
					placeholder-style="color:#909090;font-size:14px;"
					:placeholder="input.desc.length ? input.desc : '请填写' + input.name" :disabled="input.show" />
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'select'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<!-- #ifdef MP-BAIDU -->
				<u-picker @close="pickerBox = false" @cancel="pickerBox = false" @confirm="pickerConfirm"
					:show="pickerBox" v-show="pickerBox" closeOnClickOverlay :columns="[input.param]"
					:defaultIndex="getdefaultIndex(input)"></u-picker>
				<!-- #endif -->
				<!-- #ifndef MP-BAIDU -->
				<u-picker @close="pickerBox = false" @cancel="pickerBox = false" @confirm="pickerConfirm"
					:show="pickerBox" closeOnClickOverlay :columns="[input.param]"
					:defaultIndex="getdefaultIndex(input)"></u-picker>
				<!-- #endif -->

				<view class="input" @click="pickerBox = true">
					<view>
						{{ result.length ? result : input.desc.length ? input.desc : '请选择' }}
					</view>
					<view class="gengduo">
						<u-icon name="arrow-right"></u-icon>
					</view>
				</view>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'input-number'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<input type="number" class="input" :placeholder="input.desc.length ? input.desc : '请填写' + input.name"
					v-model="result" placeholder-style="color:#909090;font-size:14px" />
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'input-password'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<input type="password" class="input" :placeholder="input.desc.length ? input.desc : '请填写' + input.name"
					v-model="result" placeholder-style="color:#909090;font-size:14px" />
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'radio'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9;border-radius: 5px;">
				<u-radio-group v-model="result" placement="column" @change="groupChange">
					<u-radio :customStyle="{ marginBottom: '8px' }" v-for="(item, index) in input.param" :key="index"
						:label="item" :name="item" :activeColor="color">
					</u-radio>
				</u-radio-group>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'checkbox'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9;border-radius: 5px;">
				<u-checkbox-group v-model="result" placement="column" @change="checkboxChange">
					<u-checkbox :customStyle="{ marginBottom: '8px' }" v-for="(item, index) in input.param" :key="index"
						:label="item" :name="item" :activeColor="color">
					</u-checkbox>
				</u-checkbox-group>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'date'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<u-calendar :show="dateBox" @close="dateBox = false" @cancel="dateBox = false" @confirm="dateconfirm"
					:defaultDate="[result]" closeOnClickOverlay :color="color"></u-calendar>
				<view class="input" @click="dateBox = true">
					<view>
						{{ result.length ? result : input.desc.length ? input.desc : '请选择' }}
					</view>
					<view class="gengduo">
						<u-icon name="arrow-right"></u-icon>
					</view>
				</view>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'slider'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9;border-radius: 5px;">
				<u-slider v-model="result" :min="Number(input.param[0])"
					:max="input.param[1] ? Number(input.param[1]) : 100"
					:step="input.param[2] ? Number(input.param[2]) : 1" showValue :activeColor="color"></u-slider>
			</view>
			<view v-if="input.desc" style="font-size: 12px; color: #999; margin: 4px 0 0 4px;">
				{{ input.desc }}
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'img'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" multiple
					:maxCount="isArray && input.param[0] ? input.param[0] : 1" :previewFullImage="true"></u-upload>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'video'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view>
				<u-upload :fileList="videoList" @afterRead="upvideo" @delete="deleteV" multiple
					:maxCount="isArray && input.param[0] ? input.param[0] : 1" :previewFullImage="true"
					accept='video'></u-upload>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'rate'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view
				style="padding: 10px;background-color: #f9f9f9;border-radius: 5px;display: flex;flex-direction: row; justify-content: space-between;">
				<u-rate v-model="result" size="28" :inactiveColor="color" :activeColor="color"></u-rate>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'time'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<!-- #ifdef MP-BAIDU -->
			<u-datetime-picker closeOnClickOverlay v-show="timeBox" :show="timeBox" @confirm="confirmTime"
				@close="timeBox = false" @cancel="timeBox = false" v-model="result" mode="time"></u-datetime-picker>
			<!-- #endif -->
			<!-- #ifndef MP-BAIDU -->
			<u-datetime-picker closeOnClickOverlay :show="timeBox" @confirm="confirmTime" @close="timeBox = false"
				@cancel="timeBox = false" v-model="result" mode="time"></u-datetime-picker>
			<!-- #endif -->

			<view class="input" @click="timeBox = true">
				<view>
					{{ result.length ? result : input.desc.length ? input.desc : '请选择' }}
				</view>
				<view class="gengduo">
					<u-icon name="arrow-right"></u-icon>
				</view>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'switch'">
			<view class="name">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9;border-radius: 5px;display: flex;flex-direction: row;">
				<u-switch :activeColor="color" v-model="switchRes" @change="switchchange"></u-switch>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'code'">
			<view class="name" v-if="input.name.length">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9;">
				<view style="justify-content: space-between;
				border-radius: 5px;display: flex;flex-direction: row;">
					<input type="number" style="flex: 1;color: #666;font-size: 14px;color:#909090;" placeholder="请输入手机号"
						v-model="result" placeholder-style="color:#909090;font-size:14px">
					<view class="get-code" :style="{ color: color }" v-if="time == 0" @click="getCode">获取验证码</view>
					<view class="get-code" :style="{ color: '#666' }" v-else @click="getCode">{{ time }}秒后重新获取</view>
				</view>

				<view v-if="sendCode"
					style="margin-top: 5px;border-top: #d6d6d6 dashed 1px;padding-top: 5px;display: flex;flex-direction: row;">
					<view style="width: 90px;flex-shrink: 0;margin-right: 5px;">
						<input
							style="background: #fff;padding: 6px;border-radius: 4px;border: 1px #d6d6d6 solid;flex-shrink: 0;"
							placeholder="验证码" type="number" v-model="code" @input="changeCode"
							placeholder-style="color:#909090;font-size:14px"></input>
					</view>
					<text style="color: #ff5500;font-size: 12px;margin-top: 9px;"
						v-if="!result || !result.length">*手机号码不能为空</text>
					<text style="color: #ff5500;font-size: 12px;margin-top: 9px;"
						v-else-if="!code.length">*验证码不能为空</text>
				</view>
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'input-tag'">
			<!-- show是否为展示标签 -->
			<view class="name" v-if="input.name.length">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view v-if="!input.show" style="display: flex; align-items: stretch;">
				<view style="flex: 1;">
					<input style="border-radius: 5px 0 0 5px;" class="input"
						:placeholder="input.desc.length ? input.desc : '请填写' + input.name" v-model="tagInput"
						placeholder-style="color:#909090;font-size:14px" @confirm="addTag" />
				</view>
				<view
					style="display: flex; align-items: center; padding: 0 10px; color: #fff; border-radius: 0 5px 5px 0;"
					:style="{ backgroundColor: color }" class="clickAc" @click="addTag">
					添加
				</view>
			</view>
			<view v-if="tagList.length > 0" style="display: flex; gap: 4px; flex-wrap: wrap; margin: 8px 0 0 5px;"
				:style="{ '--app-color': color }">
				<view class="tag" v-for="(item, index) in tagList" :key="index">
					<view>{{ item }}</view>
					<view v-if="!input.show" style="margin-left: 4px;" @click="deleteTag(index)">
						<u-icon name="close" size="14" top="4" :color="color"></u-icon>
					</view>
				</view>
			</view>
			<view v-if="input.param && !input.show" style="font-size: 12px; color: #999; margin: 4px 0 0 4px;">
				已添加 {{ tagList.length }} 个标签，最多可添加 {{ input.param[0] }} 个
			</view>
		</view>
		<view class="input-box" v-else-if="input.type == 'numberBox'">
			<view class="name" v-if="input.name.length">
				<view class="must" v-if="input.must == 1">*</view>{{ input.name }}
			</view>
			<view style="padding: 10px;background-color: #f9f9f9; display: flex; gap: 4px; align-items: center;">
				<view>
					<u-number-box v-model="result" :min="input.param[0] ? input.param[0] : 0"
						:max="input.param[1] ? input.param[1] : 100"
						:step="input.param[2] ? input.param[2] : 1"></u-number-box>
				</view>
				<view>{{ input.desc }}</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	name: "moxi-form",
	data() {
		return {
			switchRes: false,
			timeBox: false,
			fileList: [],
			videoList: [],
			pickerBox: false,
			dateBox: false,
			isArray: false,
			time: 0,
			code: "",
			sendCode: false,
			tagList: [],
			tagInput: "",
		};
	}, computed: {
		result: {
			get: function () {
				return this.value;
			},
			set: function (v) {
				this.$emit("input", v);
			}
		}
	},
	model: {
		prop: 'value',
		event: 'input'
	},
	props: {
		value: {
			type: String | Array,
			default() {
				return ''
			}
		},
		color: {
			type: String,
			default() {
				return ''
			}
		},
		input: {
			type: Object,
			default() {
				return {
					name: "表单名",
					type: "input-text",
					empty: 0,
					desc: "请输入表单名",
					value: "",
					param: [],
					color: "",
					defaultDateMultiple: ""
				}
			}
		}
	}, mounted() {


	}, created() {

		if (Array.isArray(this.value)) {
			this.isArray = true;
		}
		if (this.input.type == 'img') {
			if (this.input.value && this.input.value.length) {
				if (this.isArray) {
					for (let k in this.input.value) {
						this.fileList.push({
							status: 'success',
							message: '',
							url: this.input.value[k]
						})
					}
				} else {

					this.fileList.push({
						status: 'success',
						message: '',
						url: this.input.value
					})
				}
			}
		} else if (this.input.type == 'video') {
			if (this.input.value && this.input.value.length) {
				if (this.isArray) {
					for (let k in this.input.value) {
						this.videoList.push({
							status: 'success',
							message: '',
							url: this.input.value[k]
						})
					}
				} else {
					this.videoList.push({
						status: 'success',
						message: '',
						url: this.input.value
					})
				}
			}
		} else if (this.input.type == 'switch') {
			if (this.input.value == 1) {
				this.switchRes = true;
			} else {
				this.switchRes = false;
			}
		} else if (this.input.type == 'code') {//获取验证码之前先初始化表单数据
			this.$appData.code = '';
		} else if (this.input.type == 'input-tag') {
			if (Array.isArray(this.input.value)) {
				// 检查初始标签数量是否超过了最大限制
				if (this.input.param && !this.input.show && this.input.param[0] && this.input.value.length > this.input.param[0]) {
					console.warn(`初始标签数量(${this.input.value.length})超过了最大限制(${this.input.param[0]})`);
					this.tagList = [...this.input.value.slice(0, this.input.param[0])];
				} else {
					this.tagList = [...this.input.value];
				}
			}
		}
	}, methods: {
		changeCode(e) {//填写验证码后通过this.$appData.code获取
			this.$appData.code = this.code;
		},
		getCode() {
			if (this.time > 0) {
				this.msg('请' + (this.time) + '秒后再试');
				return;
			} else {
				if (!this.result) {
					this.msg('请输入手机号码');
					return
				}
				this.moxiPost("/index/app/get_code", { phone: this.result }, (data) => {
					this.time = 60;
					this.sendCode = true;
					let s = setInterval(() => {
						if (this.time <= 0) {
							clearInterval(s);
						} else {
							this.time--;
						}
					}, 1000)
					this.msg(data.hint);
				})
			}
		},
		switchchange(e) {
			if (e) {
				this.$emit("input", 1);
			} else {
				this.$emit("input", 0);
			}
		},
		confirmTime(e) {
			this.timeBox = false;
		},
		deleteV(event) {
			this[`videoList${event.name}`].splice(event.index, 1)
			if (this.isArray) {
				this.result.splice(event.index, 1)
			} else {
				this.result = "";
			}
			this.$emit("change", this.result);
		},
		deletePic(event) {
			this[`fileList${event.name}`].splice(event.index, 1)
			if (this.isArray) {
				this.result.splice(event.index, 1)
			} else {
				this.result = "";
			}
			this.$emit("change", this.result);
		},
		afterRead(event) {
			// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
			let lists = [].concat(event.file)
			let fileListLen = this[`fileList${event.name}`].length
			lists.map((item) => {
				this[`fileList${event.name}`].push({
					...item,
					status: 'uploading',
					message: '上传中'
				})
			})
			for (let i = 0; i < lists.length; i++) {
				this.moxiUpload(lists[i].url, (data) => {
					if (this.isArray) {
						this.result.push(data);
					} else {
						this.result = data;
					}
					this.$emit("change", this.result);
					let item = this[`fileList${event.name}`][fileListLen]
					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: data
					}))
					fileListLen++
				})
			}
		},
		upvideo(event) {

			// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
			let lists = [].concat(event.file)
			let fileListLen = this[`videoList${event.name}`].length
			lists.map((item) => {
				this[`videoList${event.name}`].push({
					...item,
					status: 'uploading',
					message: '上传中'
				})
			})

			for (let i = 0; i < lists.length; i++) {
				this.moxiUpload(lists[i].url, (data) => {

					let item = this[`videoList${event.name}`][fileListLen]
					if (this.isArray) {
						this.result.push(data);
					} else {
						this.result = data;
					}
					this.$emit("change", this.result);
					this[`videoList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: data
					}))
					fileListLen++
				}, 'video')
			}
		},
		dateconfirm(e) {
			if (e.length) {
				this.result = e[0];
			} else {
				this.result = '';
			}
			this.dateBox = false
		},
		getdefaultIndex(input) {
			for (let k in input.param) {
				if (input.param[k] == this.value) {
					return [Number(k)];
				}
			}
			return [];
		},
		groupChange(e) {

			this.result = e;
		},
		pickerConfirm(e) {
			if (e.value.length) {
				this.result = e.value[0];
			} else {
				this.result = '';
			}
			this.pickerBox = false

		}
	},
	methods: {
		addTag() {
			if (this.tagInput.trim() !== '') {
				// 检查标签是否已存在
				if (this.tagList.includes(this.tagInput.trim())) {
					this.msg('标签已存在')
					return;
				}
				// 检查是否超过了最大标签数量限制
				if (this.input.param[0] && this.tagList.length >= this.input.param[0]) {
					this.msg(`最多只能添加${this.input.param[0]}个标签`)
					return;
				}
				this.tagList.push(this.tagInput.trim());
				this.tagInput = '';
				// 同步tagList到value
				this.$emit('input', this.tagList);
			}
		},
		deleteTag(index) {
			this.tagList.splice(index, 1);
			// 同步tagList到value
			this.$emit('input', this.tagList);
		},
		//获取焦点
		getFocus() {
			this.$emit("getFocus", this.input)
		},
		//失去焦点
		getBlur(e) {
			this.$emit("getBlur", this.input, e.detail.value)
		},
		getCode() {
			if (this.time > 0) {
				this.msg('请' + (this.time) + '秒后再试');
				return;
			} else {
				if (!this.result) {
					this.msg('请输入手机号码');
					return
				}
				this.moxiPost("/index/app/get_code", { phone: this.result }, (data) => {
					this.time = 60;
					this.sendCode = true;
					let s = setInterval(() => {
						if (this.time <= 0) {
							clearInterval(s);
						} else {
							this.time--;
						}
					}, 1000)
					this.msg(data.hint);
				})
			}
		},
		switchchange(e) {
			if (e) {
				this.$emit("input", 1);
			} else {
				this.$emit("input", 0);
			}
		},
		confirmTime(e) {
			this.timeBox = false;
		},
		deleteV(event) {
			this[`videoList${event.name}`].splice(event.index, 1)
			if (this.isArray) {
				this.result.splice(event.index, 1)
			} else {
				this.result = "";
			}
			this.$emit("change", this.result);
		},
		deletePic(event) {
			this[`fileList${event.name}`].splice(event.index, 1)
			if (this.isArray) {
				this.result.splice(event.index, 1)
			} else {
				this.result = "";
			}
			this.$emit("change", this.result);
		},
		afterRead(event) {
			// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
			let lists = [].concat(event.file)
			let fileListLen = this[`fileList${event.name}`].length
			lists.map((item) => {
				this[`fileList${event.name}`].push({
					...item,
					status: 'uploading',
					message: '上传中'
				})
			})
			for (let i = 0; i < lists.length; i++) {
				this.moxiUpload(lists[i].url, (data) => {
					if (this.isArray) {
						this.result.push(data);
					} else {
						this.result = data;
					}
					this.$emit("change", this.result);
					let item = this[`fileList${event.name}`][fileListLen]
					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: data
					}))
					fileListLen++
				})
			}
		},
		upvideo(event) {

			// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
			let lists = [].concat(event.file)
			let fileListLen = this[`videoList${event.name}`].length
			lists.map((item) => {
				this[`videoList${event.name}`].push({
					...item,
					status: 'uploading',
					message: '上传中'
				})
			})

			for (let i = 0; i < lists.length; i++) {
				this.moxiUpload(lists[i].url, (data) => {

					let item = this[`videoList${event.name}`][fileListLen]
					if (this.isArray) {
						this.result.push(data);
					} else {
						this.result = data;
					}
					this.$emit("change", this.result);
					this[`videoList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: data
					}))
					fileListLen++
				}, 'video')
			}
		},
		dateconfirm(e) {
			if (e.length) {
				this.result = e[0];
			} else {
				this.result = '';
			}
			this.dateBox = false
		},
		getdefaultIndex(input) {
			for (let k in input.param) {
				if (input.param[k] == this.value) {
					return [Number(k)];
				}
			}
			return [];
		},
		groupChange(e) {

			this.result = e;
		},
		pickerConfirm(e) {
			if (e.value.length) {
				this.result = e.value[0];
			} else {
				this.result = '';
			}
			this.pickerBox = false

		}
	}
}
</script>

<style lang="scss" scoped>
.get-code {
	font-size: 13px;
	margin-top: 2px;
}

.gengduo {
	margin-top: 2px;
}

.input {
	padding: 10px;
	border-radius: 5px;
	background: #f9f9f9;
	color: #909090;
	font-size: 14px;
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	color: #909090
}

.input-box {
	display: flex;
	flex-direction: column;
	margin: 5px 0;
}

.name {
	color: #666;
	font-weight: bold;
	margin: 5px;
	font-size: 14px;
	flex-shrink: 0;
	display: flex;
	flex-direction: row;
}

.must {
	color: red;
	margin-right: 3px;
}

.tag {
	display: flex;
	align-items: stretch;
	font-size: 14px;
	padding: 2px 4px;
	border-radius: 4px;
	border: 1px solid var(--app-color);
	color: var(--app-color);

	position: relative;
	overflow: hidden;

	&::before {
		content: '';
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: var(--app-color);
		opacity: .1;
	}
}

.clickAc:active {
	& {
		position: relative;
		overflow: hidden;
	}

	&::before {
		content: '';
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.1);
	}
}
</style>